%%%-------------------------------------------------------------------
%%% @author Administrator
%%% @copyright (C) 2019, <COMPANY>
%%% @doc
%%%
%%% @end
%%% Created : 30. 12月 2019 10:04
%%%-------------------------------------------------------------------
-module(game_util).
-compile(export_all).
-compile(nowarn_export_all).
-author("Administrator").
-include("../include/player.hrl").
-include("../include/game.hrl").
-include("../include/myshare.hrl").
-include("../include/logger.hrl").

%% API

-spec(ws_conn_game(Game_Id :: string()) -> {ok, pid()}).
ws_conn_game(Game_Id) ->
  Game_Name =
    case Game_Id of
      ?NIU_NIU -> "niuniu";
      ?SAN_GONG -> "sangongn"
    end,
  WsHost = myshare:get_env(ws_host),
  WsPort = myshare:get_env(ws_port),
  {ok, ConnPid} = gun:open(WsHost, WsPort),
  PlayerInfo = player_assist:get_at_player_info(),
  Token = PlayerInfo#player_info.token,
  gun:ws_upgrade(ConnPid, "/" ++ Game_Name ++ "/" ++ Token ++ "/0", []),
  {ok, ConnPid}.

%%根据游戏id获取连接标识
-spec game_conn_name(GameId :: integer()) -> string().
game_conn_name(GameId) ->
  GameName =
    case GameId of
      2 -> "niniu";
      3 -> "sangong";
      _ -> ""
    end,
  GameName.


%%初始化房间座位信息
init_room_index(GameId, RoomId) ->
  case ets:lookup(?ETS_ROOM_SEAT, RoomId) of
    [] ->
      Now = sys_util:timestamp(),
      init_room_queue(GameId, RoomId),
      case GameId of
        ?NIU_NIU_MING_PAI ->
          ets:insert(?ETS_ROOM_SEAT,
            #room_seat_info{
              game_id = GameId,
              room_id = RoomId,
              seat = [0, 1, 2, 3, 4, 5, 6, 7],
              created_at = Now
            });
        ?WEI_NIU ->
          ets:insert(?ETS_ROOM_SEAT,
            #room_seat_info{
              game_id = GameId,
              room_id = RoomId,
              seat = [0, 1, 2, 3],
              created_at = Now
            });
        _ ->
          ets:insert(?ETS_ROOM_SEAT, #room_seat_info{game_id = GameId, room_id = RoomId, created_at = Now})
      end;
    _ -> ok
  end.
%%初始化房间排队信息
init_room_queue(GameId, RoomId) ->
  case ets:lookup(?ETS_ROBOT_QUEUE, RoomId) of
    [] ->
      case GameId of
        ?NIU_NIU_MING_PAI ->
          Index2 = #{
            0 => [],
            1 => [],
            2 => [],
            3 => [],
            4 => [],
            5 => [],
            6 => [],
            7 => []
          },
          ets:insert(?ETS_ROBOT_QUEUE, #robot_queue{game_id = GameId, room_id = RoomId, index = Index2});
        ?WEI_NIU ->
          Index2 = #{
            0 => [],
            1 => [],
            2 => [],
            3 => []
          },
          ets:insert(?ETS_ROBOT_QUEUE, #robot_queue{game_id = GameId, room_id = RoomId, index = Index2});
        _ -> ets:insert(?ETS_ROBOT_QUEUE, #robot_queue{game_id = GameId, room_id = RoomId})
      end;

    _ -> ok
  end.

%%获取房间座位信息
-spec get_room_index(RoomId :: integer()) -> list().
get_room_index(RoomId) ->
  [RoomSeat] = ets:lookup(?ETS_ROOM_SEAT, RoomId),
  RoomSeat#room_seat_info.seat.

%%抢庄下注倍数计算
-spec get_bets_multiple(Type :: integer()) -> integer().
get_bets_multiple(Type) ->
  N = rand:uniform(8),
  N2 =
    case 9 rem N of
      0 -> 2; %2/8
      4 -> 3; %1/8
      _ -> 1 % 5/8
    end,
  case Type of %1抢庄 2 闲家下注
    1 -> lists:nth(N2, ?ROB_ZHUANG);
    2 -> lists:nth(N2, ?ROB_BOTTOM);
    _ -> 1
  end.

%%发牌整理
get_mingpai_bet_num(Puke) ->
  Puke2 = lists:droplast(Puke),
  lists:foldl(
    fun(P, Acc) ->
      {K, V} = Acc,
      Value = binary_to_list(P),
      V1 = string:substr(Value, 1, 1),
      V2 = list_to_integer(string:substr(Value, 2, 2)),
      {[V1 | K], [V2 | V]}
    end, {[], []}, Puke2
  ).

%%是否是顺子
is_sun_zi(List) ->
  List2 = lists:sort(List),
  {_, Sun_zi} = lists:foldl(
    fun(N, {Acc, Is_sz}) ->
      if
        Acc =:= false -> {Acc, Is_sz};
        Acc =:= -1 -> {N, false};
        Acc + 1 =:= N -> {N, true};
        true -> {Acc, false}
      end
    end, {-1, false}, List2),
  Sun_zi.

%%是否4张间隔顺子
interval_shunza(A) ->
  B1 = lists:sublist(A, 1, 3),
  B2 = lists:sublist(A, 2, 3),
  C1 = lists:nth(1, A),
  C2 = lists:nth(2, A),
  C3 = lists:nth(3, A),
  C4 = lists:nth(4, A),
  S1 = is_sun_zi(B1),
  S2 = is_sun_zi(B2),
  if
    S1 =:= true andalso C3 + 2 =:= C4 -> true;
    S2 =:= true andalso C1 + 2 =:= C2 -> true;
    true -> false
  end.

%%判断是否有牛,牛几
niu_number(Pai_val) ->
  NumList = lists:seq(1, 4),
  Fun2 = fun(N, Acc) ->
    NewList = NumList -- [N],
    Sum2 = lists:foldl(
      fun(N2, Acc2) ->
        NewVal = lists:nth(N2, Pai_val),
        if
          NewVal > 10 -> NewVal2 = 10;
          true -> NewVal2 = NewVal
        end,
        Acc2 + NewVal2
      end, 0, NewList),

    Is_niu = Sum2 rem 10,
    if
      Is_niu =:= 0 ->
        %有牛
        Pai4_1 = lists:nth(N, Pai_val),%最后一张牌算牛几
        Pai4 =
          case Pai4_1 > 10 of
            true -> 10;
            _ -> Pai4_1
          end,
        Niu_num = Pai4 rem 10,
        if
          Niu_num =:= 0 -> N2 = 10;
          true -> N2 = Niu_num
        end;
      true ->
        N2 = 0
    end,
    if
      Acc > N2 -> Acc;
      true -> N2
    end
         end,
  lists:foldl(Fun2, 0, NumList).

%分组牌值数量
pai_group(Pai_List) ->
  Fun = fun(N, Acc) ->
    case maps:is_key(N, Acc) of
      true ->
        maps:update(N, maps:get(N, Acc) + 1, Acc);
      _ ->
        maps:put(N, 1, Acc)
    end
        end,
  lists:foldl(Fun, #{}, Pai_List).

%是否是对子
is_duizi(Pai_List) ->
  maps:fold(
    fun(_K, V, AccIn) ->
      if
        AccIn =:= false -> AccIn;
        V =:= 2 -> true;
        true -> false
      end
    end, true, pai_group(Pai_List)).

%是否有三个一样的牌
is_key3(Pai_List) ->
  maps:fold(
    fun(_K, V, AccIn) ->
      if
        AccIn =:= true -> AccIn;
        V =:= 3 -> true;
        true -> AccIn
      end
    end, false, pai_group(Pai_List)).



%%明牌闲家下注特殊牌型下注倍数
get_bet_num(Puke) ->
  case Puke of
    undefined -> 1;
    [] -> 1;
    _ ->
      {K, V} = get_mingpai_bet_num(Puke),
      V2 = lists:sort(V),
      K_num = erlang:length(lists:usort(K)), %值为1是同花色
      Is_duizi = is_duizi(V2), %值为2是对子
      Is_key3 = is_key3(V2),%是否有3个一样
      Is_even_card = is_sun_zi(V2),%是否连牌
      Niu_num = niu_number(V2),%牛数量
      Shunza = interval_shunza(V2),%间隔顺子
      Sum = lists:sum(V),%牌求和
      ?WARNING("puke:~p, niu_num:~p;k_num:~p;is_duizi:~p;key3:~p;shunzi:~p
      ;jinge_shunzi:~p", [Puke,Niu_num, K_num, Is_duizi, Is_key3, Is_even_card, Shunza]),
      case K_num of
        1 ->
          if
            Niu_num > 5 -> N5 = 99;%%牛6以上推注最大
            Is_even_card =:= true andalso Niu_num > 0 -> N5 = 99;%%4连长同花色有牛推注最大
            Shunza =:= true -> N5 = 99;%同花间隔顺子推注最大
            Niu_num > 0 andalso Niu_num < 6 -> N5 = 3; %同花色有牛牛6以下加3倍
            Is_even_card =:= true -> N5 = 3;%同花色连牌加3倍
            true -> N5 = 1
          end;
        _ ->
          if
            Niu_num =:= 10 ->
              N5 =
                case is_hua(K, V) of
                  true -> 99;
                  _ -> 3
                end;
            Is_even_card =:= true andalso Niu_num > 6 -> N5 = 3;%顺子大于牛6
            Shunza =:= true andalso Niu_num > 6 -> N5 = 3;%间隔顺子大于牛6
            Is_even_card =:= true andalso Niu_num > 0 -> N5 = 1;%顺子有牛
            Shunza =:= true andalso Niu_num > 0 -> N5 = 1;%间隔顺子有牛
            Is_duizi =:= true ->%对子
              Sum2 = number_sum_20(V),
              if
                Niu_num =:= 10 -> N5 = 99;%两对成牛推注最大
                Niu_num > 0 -> N5 = 3;%两对有牛加3倍
                Sum2 =:= 20 -> N5 = 3;%纯数字，是对子，总大小是20,加3倍
                true -> N5 = 1
              end;
            Is_key3 =:= true ->
              if
                Niu_num =:= 10 -> N5 = 99;%三张一样牛牛推注最大
                Niu_num > 0 -> N5 = 3;%三张一样有牛加3
                true -> N5 = 1
              end;
            Sum < 6 -> N5 = 99; %牌总和小于6推注最大
            true -> N5 = 1
          end
      end,
      N5
  end.

%%纯数字，是对子，总大小是20
number_sum_20(Puke_val) ->
  List2 = [Val || Val <- Puke_val, Val < 11],
  lists:sum(List2).


%%是否有花牌
is_hua(KList, VList) ->
  R1 = lists:member(13, VList),
  Q = lists:member(12, VList),
  H1 = lists:member(?FLOWER_COLOR_A, KList),
  H2 = lists:member(?FLOWER_COLOR_B, KList),
  if
    R1 =:= true -> true;
    H1 =:= true andalso Q =:= true -> true;
    H2 =:= true andalso Q =:= true -> true;
    true -> false
  end.

%%是否必抢4,正常牌型和特殊牌
will_rob4(Puke, Num) ->
  {_, V} = get_mingpai_bet_num(Puke),
  V2 = lists:sort(V),
  Niu_num = niu_number(V2),%牛数量
  Special = lists:member(0, V2),%是否有特殊牌
  if
    Special =:= true -> true;
    Niu_num > Num -> true;
    true -> false
  end.

%%获取牌型
get_puke(Account) ->
  case ets:lookup(?ETS_MING_PAI_SCHEDULE, Account) of
    [] -> [];
    [Puke] -> Puke
  end.

%%计算明牌抢庄倍数
ming_pai_zhuang_number(Room_id, Account) ->
  Ming_pai_players = ets:select(?ETS_MING_PAI_SCHEDULE, [{#ming_pai_player{room_id = Room_id, _ = '_'}, [], ['$_']}]),
  ?DEBUG("Ming_pai_players :~p", [Ming_pai_players]),

  case Ming_pai_players of
    [] -> 1;
    _ ->
      Player_niu_num =
        lists:foldl(fun(#ming_pai_player{account = Account2, match = Match}, Acc) ->
          {_, Pai_val} = game_util:get_mingpai_bet_num(Match),
          Niu_num = game_util:niu_number(Pai_val),
          maps:put(Account2, Niu_num, Acc)
                    end, #{}, Ming_pai_players),

      Map_value = maps:values(Player_niu_num),
      Max = lists:max(Map_value),

      %当前玩家牛几
      Random2 =
        case sys_util:random(2) of
          1 -> 2;
          _ -> 0
        end,

      Num2 =
        case maps:get(Account, Player_niu_num, 0) of
          0 -> 0;%无牛不抢
          Max ->
            case erlang:get(Room_id) of
              true -> Random2;
              _ ->
                erlang:put(Room_id, true),
                4
            end;
          _->Random2
        end,
      PlayerInfo2 = player_assist:get_player_info(Account),
      Puke2 = get_puke(Account),
      ?WARNING("ming_pai_qiangzhuang account:~p,name:~ts,puke:~p,num:~p", [Account,PlayerInfo2#player_info.nickName,Puke2#ming_pai_player.match, Num2]),
      Num2
  end.














